# 标准库
from datetime import datetime, timezone
import os
from werkzeug.utils import secure_filename

# 本地模块
from inc.models import db, JiraTask, JiraStage, AdminMember, JiraMember, TaskAttachment
from inc.config import Config

def get_project_members(stage_id):
    """获取项目成员列表"""
    stage = JiraStage.query.get_or_404(stage_id)
    project = stage.project

    # 获取项目成员
    members = []
    for jira_member in project.members:
        member = jira_member.member
        if member and member.status:  # 只返回有效的成员
            members.append({
                'id': member.id,
                'name': member.name,
                'position': member.position
            })

    return members

def get_tasks(user_id, status_filter='all'):
    """获取用户的任务列表"""
    query = JiraTask.query.filter_by(assignee_id=user_id)

    if status_filter != 'all':
        query = query.filter_by(status=status_filter)

    return query.order_by(JiraTask.due_date.desc()).all()

def create_task(stage_id, user_id, form_data, files=None):
    """创建任务，使用经过验证的表单数据"""
    stage = JiraStage.query.get_or_404(stage_id)

    # 权限检查：只有项目成员才能创建任务
    if not any(m.member_id == user_id for m in stage.project.members):
        raise PermissionError("只有项目成员才能创建任务")

    # 验证负责人是否是项目成员
    assignee_id = form_data.get('assignee_id')
    if not any(m.member_id == assignee_id for m in stage.project.members):
        raise ValueError("选择的负责人不是项目成员")

    task = JiraTask(
        name=form_data['name'],
        description=form_data.get('description'),
        stage_id=stage_id,
        assignee_id=assignee_id,
        due_date=form_data.get('due_date'),
        priority=form_data.get('priority', 'medium'),
        status='todo'  # 初始状态
    )
    db.session.add(task)
    db.session.commit()

    # 处理上传的文件
    if files:
        for file in files:
            if file and file.filename:
                upload_attachment(task.id, user_id, file, '任务创建时上传')

    return task

def assign_task(task_id, user_id, assignee_id):
    """分配任务"""
    task = JiraTask.query.get_or_404(task_id)

    # 权限检查：只有项目负责人可以分配任务
    if task.stage.project.owner_id != user_id:
        raise PermissionError("只有项目负责人可以分配任务")

    if not assignee_id:
        raise ValueError("请选择要分配的成员")

    # 验证负责人是否是项目成员
    if not any(m.member_id == int(assignee_id) for m in task.stage.project.members):
        raise ValueError("选择的负责人不是项目成员")

    task.assignee_id = assignee_id
    task.status = 'todo' # 分配后重置为待办
    db.session.commit()
    return task

def accept_task(task_id, user_id):
    """接受任务"""
    task = JiraTask.query.get_or_404(task_id)

    # 权限检查
    if task.assignee_id != user_id:
        raise PermissionError("只有任务负责人可以接受任务")

    if task.status != 'todo':
        raise ValueError("只能接受'待办'状态的任务")

    task.status = 'in_progress'
    task.started_at = datetime.now(timezone.utc)
    db.session.commit()
    return task

def start_task(task_id, user_id):
    """开始任务 (逻辑上与接受任务合并，保留以兼容旧接口)"""
    return accept_task(task_id, user_id)

def update_task_progress(task_id, user_id, progress):
    """更新任务进度"""
    task = JiraTask.query.get_or_404(task_id)

    if task.assignee_id != user_id:
        raise PermissionError("只有任务负责人可以更新进度")

    if task.status != 'in_progress':
        raise ValueError("只能更新'进行中'任务的进度")

    if not 0 <= progress <= 100:
        raise ValueError("进度必须在0-100之间")

    task.progress = progress
    db.session.commit()
    return task

def complete_task(task_id, user_id):
    """完成任务"""
    task = JiraTask.query.get_or_404(task_id)

    # 检查权限
    if task.assignee_id != user_id:
        raise PermissionError("只有任务负责人可以完成任务")

    if task.status not in ['in_progress', 'review']:
        raise ValueError("只能完成'进行中'或'审核中'的任务")

    task.status = 'completed'
    task.progress = 100
    task.completed_at = datetime.now(timezone.utc)
    db.session.commit()
    return task

def get_task_detail(task_id):
    """获取任务详情"""
    task = JiraTask.query.get_or_404(task_id)
    return task

def rate_task(task_id, user_id, form_data):
    """评价任务"""
    task = JiraTask.query.get_or_404(task_id)

    # 权限检查：只有项目负责人可以评价任务
    if task.stage.project.owner_id != user_id:
        raise PermissionError("只有项目负责人可以评价任务")

    if task.status != 'completed':
        raise ValueError("只能评价已完成的任务")

    rating = form_data.get('rating')
    if not isinstance(rating, int) or not 1 <= rating <= 5:
        raise ValueError("评分必须是1到5之间的整数")

    task.rating = rating
    task.comment = form_data.get('comment', '')
    db.session.commit()
    return task

def upload_attachment(task_id, user_id, file, description=''):
    """上传任务附件"""
    task = JiraTask.query.get_or_404(task_id)

    # 权限检查：只有任务负责人或项目负责人可以上传附件
    if task.assignee_id != user_id and task.stage.project.owner_id != user_id:
        raise PermissionError("只有任务负责人或项目负责人可以上传附件")

    if not file or file.filename == '':
        raise ValueError("请选择有效的文件")

    # 处理文件名，保留中文
    filename = file.filename
    # 仅过滤特殊字符
    filename = ''.join(c for c in filename if c.isalnum() or c in (' ', '.', '_', '-'))
    filename = filename.strip()

    # 确保上传目录存在
    uploads_dir = os.path.join(Config.UPLOAD_FOLDER, 'attachments')
    if not os.path.exists(uploads_dir):
        os.makedirs(uploads_dir)

    # 保存文件
    filepath = os.path.join(uploads_dir, filename)
    file.save(filepath)

    # 创建附件记录
    attachment = TaskAttachment(
        task_id=task_id,
        filename=filename,
        filepath=filepath,
        description=description,
        uploader_id=user_id
    )
    db.session.add(attachment)
    db.session.commit()
    return attachment

def download_attachment(attachment_id, user_id):
    """下载任务附件"""
    from flask import send_from_directory
    import os
    from inc.config import Config

    attachment = TaskAttachment.query.get_or_404(attachment_id)

    # 权限检查：只有任务相关成员可以下载附件
    if (attachment.task.assignee_id != user_id and
        attachment.task.stage.project.owner_id != user_id and
        not any(m.member_id == user_id for m in attachment.task.stage.project.members)):
        raise PermissionError("无权下载此附件")

    # 检查文件是否存在
    uploads_dir = os.path.join(Config.UPLOAD_FOLDER, 'attachments')
    file_path = os.path.join(uploads_dir, attachment.filename)

    if not os.path.exists(file_path):
        raise ValueError(f"附件文件不存在: {attachment.filename}。可能已被删除或移动，请联系管理员")

    # 返回文件下载响应
    return send_from_directory(
        uploads_dir,
        attachment.filename,
        as_attachment=True,
        download_name=attachment.filename
    )

def delete_attachment(attachment_id, user_id):
    """删除任务附件"""
    from werkzeug.security import safe_join
    from inc.config import Config

    attachment = TaskAttachment.query.get_or_404(attachment_id)
    task = attachment.task

    # 简化权限检查：编辑页已做权限验证
    if not task or not task.stage or not task.stage.project:
        raise PermissionError("无效的任务或项目信息")

    # 保留任务状态检查
    if task.status in ['completed', 'closed']:
        raise PermissionError("不能删除已完成或已关闭任务的附件")

    # 安全构建文件路径
    uploads_dir = safe_join(Config.UPLOAD_FOLDER, 'attachments')
    file_path = safe_join(uploads_dir, attachment.filename)

    if not file_path:  # 安全检查失败
        raise ValueError("无效的文件路径")

    # 删除文件
    if os.path.exists(file_path):
        try:
            os.remove(file_path)
        except OSError as e:
            raise ValueError(f"删除文件失败: {str(e)}")

    # 删除记录
    db.session.delete(attachment)
    db.session.commit()
    return True